﻿using SharpDepend.Classes;
using SharpDepend.Classes.ProfileredDatatypes.Collections.Generic;
using SharpDepend.Controls;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SharpDepend.WP8
{
    class GraphicsDisplayManager : IGraphicsDisplayManager
    {
        private PList<GraphicDevice> mAvailableDevices;
        private PList<IGraphicsDisplay> mUsedDisplays;

        public GraphicDevice CurrentUsingDevice { get; private set; }

        public GraphicsDisplayManager()
        {
            mAvailableDevices = new PList<GraphicDevice>("Available devices", this);
            mUsedDisplays = new PList<IGraphicsDisplay>("Used displays", this);
            CurrentUsingDevice = null;
        }
        
        public IGraphicsDevice CreateDevice(GraphicDevice device)
        {
            IGraphicsDevice gdevice = (IGraphicsDevice)Activator.CreateInstance(device.GraphicsDeviceType);
            gdevice.Enable = true; // TODO: Ska vi ens ha dendär? :O
            return gdevice;
        }

        public void SetupDisplay(IGraphicsDisplay display)
        {
            mUsedDisplays.Add(display);

            var device = CreateDevice(CurrentUsingDevice);
            display.GraphicsDeviceChanged(device);
            device.Initialize(display);
        }

        public void AddMultitouch(IGraphicsDisplay display)
        {
            // Registration of multitouch and mouse.
            IMultiTouch multitouchController = SharpDepend.Manager.MultiTouch.CreateMultiTouch<IGraphicsDisplay>(display);
            TouchManager.Instance.RegisterTouchListener(display, multitouchController);
        }

        public IGraphicsDisplay CreateGraphicsDisplay()
        {
            IGraphicsDisplay display = new GraphicsDisplay();

            SetupDisplay(display);

            return display;
        }

        public void SetGraphicsDevice(GraphicDevice device)
        {
            if (device == null)
            {
                throw new NullReferenceException("device");
            }
            if (!mAvailableDevices.Contains(device))
            {
                throw new Exception("Device " + device + " must be added before to be used.");
            }

            //if (CurrentUsingDevice != device)
            //{
                CurrentUsingDevice = device;

                foreach (var display in mUsedDisplays)
                {
                    // Do not change device when display has a manually set device.
                    if (display.ManualGraphicsDevice == null)
                    {
                        var cdevice = CreateDevice(CurrentUsingDevice);
                        display.GraphicsDeviceChanged(cdevice);
                        cdevice.Initialize(display);
                    }
                }
            //}
        }

        public void AddDevice(GraphicDevice device)
        {
            if (device == null)
            {
                throw new NullReferenceException("device");
            }
            if (mAvailableDevices.Contains(device))
            {
                throw new Exception("Device " + device + " already exist.");
            }
            mAvailableDevices.Add(device);
        }

        public IEnumerable<GraphicDevice> AvailableDevices
        {
            get { return mAvailableDevices; }
        }

        public IEnumerable<IGraphicsDisplay> GraphicsDisplaysInUse
        {
            get { return mUsedDisplays; }
        }
    }
}
